package cn.aezo.minions.web.services.impl;

import cn.aezo.minions.common.Result;
import cn.aezo.minions.gen.mapper.TemplateDao;
import cn.aezo.minions.gen.mapper.TemplateItemDao;
import cn.aezo.minions.gen.model.Template;
import cn.aezo.minions.gen.model.TemplateItem;
import cn.aezo.minions.utils.SmUtils;
import cn.aezo.minions.utils.ZipU;
import cn.aezo.minions.web.services.TemplateService;
import cn.aezo.utils.base.MiscU;
import cn.aezo.utils.base.ValidU;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author smalle
 * @date 2019-08-02 17:52
 */
@Component
public class TemplateServiceImpl implements TemplateService {
    @Autowired
    TemplateDao templateDao;

    @Autowired
    TemplateItemDao templateItemDao;

    /**
     * 获取模板树
     * @param dbList
     * @param parentId
     * @param idName
     * @param pidName
     * @param level
     * @return
     */
    @Override
    public List<Map<String, Object>> getLevelData(List<Map<String, Object>> dbList, String parentId,
                                                  String idName, String pidName, Integer level) {
        List<Map<String, Object>> resultList = new ArrayList<>();
        for (Map<String, Object> data : dbList) {
            if (String.valueOf(parentId).equals(String.valueOf(data.get(pidName)))) {
                level = ++level;
                List<Map<String, Object>> childList = getLevelData(dbList, String.valueOf(data.get(idName)), idName, pidName, level);
                data.put("children", childList);
                if(level > 3) {
                    data.put("spread", false);
                }
                resultList.add(data);
            }
        }
        return resultList;
    }

    @Override
    public Result addTemplate(File zipFile, Template template, Long userId) {
        template.setUserId(userId);
        templateDao.insert(template);

        String dir = System.getProperty("user.dir") + "/runtime/temp/" + userId + "_" + System.currentTimeMillis();

        ZipU.unzip(zipFile, dir);

        File dirFile = new File(dir);
        File[] files = dirFile.listFiles();
        if(files != null) {
            for (File itemFile : files) {
                saveTemplateItem(itemFile, MiscU.Instance.toMap("pid", 0L,  "templateId", template.getTemplateId()));
            }
        }

        SmUtils.deleteDir(dirFile);
        return Result.success("添加模板成功");
    }

    @Override
    public Result saveTemplateItem(Long templateItemId, String templateItemValue) {
        TemplateItem templateItem = new TemplateItem();
        templateItem.setTemplateItemId(templateItemId);
        templateItem.setItemValue(templateItemValue);
        templateItemDao.updateById(templateItem);
        return Result.success();
    }

    @Override
    public Result downloadTemplate(Long templateId, Long userId) {
        Result result = getTemplateWithLevel(templateId);
        if(Result.isError(result)) return result;

        String tempDir = System.getProperty("user.dir") + "/runtime/temp/";
        String tempProjectDir = userId + "_" + System.currentTimeMillis();
        String dir = tempDir + tempProjectDir;

        List<Map<String, Object>> list = (List<Map<String, Object>>) result.getData();
        if(ValidU.isNotEmpty(list)) {
            for (Map<String, Object> item : list) {
                item.put("rootDir", dir);
                makeTemplateItemFile(item);
            }
        }

        String zipFileName = tempProjectDir + ".zip";
        ZipU.zip(dir, tempDir + zipFileName);
        SmUtils.deleteDir(new File(dir));

        return Result.success(MiscU.Instance.toMap("zipFileName", zipFileName));
    }

    @Override
    public Result getTemplateWithLevel(Long templateId) {
        List<Map<String, Object>> list = templateDao.findTemplateItemList(templateId);
        if(ValidU.isEmpty(list))
            return Result.failure("无任何模板文件");
        List<Map<String, Object>> resList = getLevelData(list, "0", "id", "pid", 0);
        return Result.success(resList);
    }

    private void saveTemplateItem(File file, Map<String, Object> context) {
        Long pid = (Long) context.get("pid");
        Long templateId = (Long) context.get("templateId");

        TemplateItem templateItem = new TemplateItem();
        templateItem.setTemplateId(templateId);
        templateItem.setPid(pid);
        templateItem.setItemName(file.getName());
        if(file.isDirectory()) {
            templateItem.setItemType(1);
        } else {
            templateItem.setItemType(2);
            try {
                templateItem.setItemValue(SmUtils.read(file, true));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        templateItemDao.insert(templateItem);

        if(file.isDirectory()) {
            context.put("pid", templateItem.getTemplateItemId());

            File[] files = file.listFiles();
            if(files != null) {
                for (File itemFile : files) {
                    saveTemplateItem(itemFile, context);
                }
            }
        }
        context.put("pid", pid);
    }

    private void makeTemplateItemFile(Map<String, Object> itemContext) {
        String rootDir = (String) itemContext.get("rootDir");
        if("1".equals("" + itemContext.get("itemType"))) {
            rootDir = rootDir + "/" + itemContext.get("title");
            SmUtils.mkdir(rootDir);
            List<Map<String, Object>> children = (List<Map<String, Object>>) itemContext.get("children");
            if(ValidU.isNotEmpty(children)) {
                for (Map<String, Object> child : children) {
                    child.put("rootDir", rootDir);
                    makeTemplateItemFile(child);
                }
            }
        } else {
            try {
                SmUtils.mkdir(rootDir);
                String content = (String) itemContext.get("itemValue");
                if(ValidU.isEmpty(content)) content = "";
                SmUtils.write(rootDir + "/" + itemContext.get("title"), content, false);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
